#pragma once

#include "../umlmodel_global.h"

#include <memory>
#include <vector>

#include "DirectedRelationship.h"
#include "VisibilityKind.h"

using std::make_shared;
using std::shared_ptr;
using std::vector;

namespace uml {
class Namespace;
class Package;

/// <summary>
/// PackageImport
/// A PackageImport is a Relationship that imports all the non-private members of a
/// Package into the Namespace owning the PackageImport, so that those Elements may
/// be referred to by their unqualified names in the importingNamespace.
/// </summary>
class UMLMODEL_EXPORT PackageImport : public DirectedRelationship {

public: // JsonSerializable override
    void fromJson(const QJsonObject& json, QStringList& errorList) override;
    void toJson(QJsonObject& json) override;

public: // Properties
    /// <summary>
    /// importedPackage getter
    /// Specifies the Package whose members are imported into a Namespace.
    /// </summary>
    shared_ptr<Package> importedPackage() const;

    /// <summary>
    /// importedPackage setter
    /// Specifies the Package whose members are imported into a Namespace.
    /// </summary>
    void setImportedPackage(shared_ptr<Package> value);

    /// <summary>
    /// importingNamespace getter
    /// Specifies the Namespace that imports the members from a Package.
    /// </summary>
    shared_ptr<Namespace> importingNamespace() const;

    /// <summary>
    /// importingNamespace setter
    /// Specifies the Namespace that imports the members from a Package.
    /// </summary>
    void setImportingNamespace(shared_ptr<Namespace> value);

    /// <summary>
    /// visibility getter
    /// Specifies the visibility of the imported PackageableElements within the
    /// importingNamespace, i.e., whether imported Elements will in turn be visible to
    /// other Namespaces. If the PackageImport is public, the imported Elements will be
    /// visible outside the importingNamespace, while, if the PackageImport is private,
    /// they will not.
    /// </summary>
    VisibilityKind visibility() const;

    /// <summary>
    /// visibility setter
    /// Specifies the visibility of the imported PackageableElements within the
    /// importingNamespace, i.e., whether imported Elements will in turn be visible to
    /// other Namespaces. If the PackageImport is public, the imported Elements will be
    /// visible outside the importingNamespace, while, if the PackageImport is private,
    /// they will not.
    /// </summary>
    void setVisibility(VisibilityKind value);

private: // Fields
    /// <summary>
    /// importedPackage
    /// Specifies the Package whose members are imported into a Namespace.
    /// </summary>
    shared_ptr<Package> importedPackage_;

    /// <summary>
    /// importingNamespace
    /// Specifies the Namespace that imports the members from a Package.
    /// </summary>
    shared_ptr<Namespace> importingNamespace_;

    /// <summary>
    /// visibility
    /// Specifies the visibility of the imported PackageableElements within the
    /// importingNamespace, i.e., whether imported Elements will in turn be visible to
    /// other Namespaces. If the PackageImport is public, the imported Elements will be
    /// visible outside the importingNamespace, while, if the PackageImport is private,
    /// they will not.
    /// </summary>
    VisibilityKind visibility_ = VisibilityKind::kpublic;

};

} // namespace uml
